package errors

import (
	terrors "errors"
	"fmt"
)

type appError struct {
	code int
	reason string
}

func New(code int, reason string) *appError {
	return &appError{code: code, reason: reason}
}

func (e *appError)Error() string {
	return fmt.Sprintf("errors, code = %d, reason = %s", e.code, e.reason)
}


func Code(err error) int {
	if err == nil {
		return 200
	}
	if se := FromError(err); se != nil {
		return int(se.code)
	}
	return 500
}

// Reason returns the reason for a particular error.
// It supports wrapped errors.
func Reason(err error) string {
	if se := FromError(err); se != nil {
		return se.reason
	}
	return ""
}

// FromError try to convert an error to *Error.
// It supports wrapped errors.
func FromError(err error) *appError {
	if err == nil {
		return nil
	}

	if se := new(appError); terrors.As(err, &se) {
		return se
	}

	return New(500, "")
}



